package logic;

import com.google.gdata.client.spreadsheet.*;
import com.google.gdata.data.spreadsheet.*;

import java.net.URI;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import main.Main;

public class DriveLoader
{
	private static SpreadsheetService	service		= null;
	private static DriveLoader				INSTANCE	= null;

	private DriveLoader()
	{
		service = null;
	}

	public static synchronized DriveLoader getInstance()
	{
		if (INSTANCE == null)
		{
			INSTANCE = new DriveLoader();
		}
		return INSTANCE;
	}

	public Boolean getAccess(String username, String password)
	{
		if (service == null)
			service = new SpreadsheetService("DkpManager");
		try
		{
			service.setUserCredentials(username, password);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			Main.LOGGER.severe(e.getMessage());
			return false;
		}
		return true;
	}

	public Boolean checkSpreadsheetUrl()
	{
		try
		{
			service.getEntry(ModsLoader.spreadsheet_feed_url, SpreadsheetEntry.class);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			Main.LOGGER.severe(e.getMessage());
			return false;
		}
		return true;
	}

	public SortedSet<Person> getSpreadsheetData(String WorksheetTitle)
	{
		SortedSet<Person> res = new TreeSet<Person>();
		try
		{
			SpreadsheetEntry spreadsheet = service.getEntry(ModsLoader.spreadsheet_feed_url, SpreadsheetEntry.class);
			if (ModsLoader.debugMode)
				System.out.println("Spreadsheetentry name: " + spreadsheet.getTitle().getPlainText());

			// find Worksheet DkpLoots
			WorksheetFeed worksheetFeed = service.getFeed(spreadsheet.getWorksheetFeedUrl(), WorksheetFeed.class);
			List<WorksheetEntry> worksheets = worksheetFeed.getEntries();
			WorksheetEntry DkpLootsWorksheet = null;
			for (WorksheetEntry worksheet : worksheets)
			{
				if (worksheet.getTitle().getPlainText().equals(WorksheetTitle))
					DkpLootsWorksheet = worksheet;
			}
			if (DkpLootsWorksheet == null)
				return res;

			// Fetch column 1 & 2, and every row after row 1.
			URL cellFeedUrl = new URI(DkpLootsWorksheet.getCellFeedUrl().toString() + "?min-row=2&min-col=1&max-col=2").toURL();
			CellFeed cellFeed = service.getFeed(cellFeedUrl, CellFeed.class);

			// Iterate through each cell, printing its value.
			// i assume the list is always received sorted for now.
			String name = "";
			for (CellEntry cell : cellFeed.getEntries())
			{
				if (cell.getTitle().getPlainText().startsWith("A"))
					name = cell.getCell().getValue();
				else if (cell.getTitle().getPlainText().startsWith("B") && name.length() > 0)
				{
					try
					{
						long total_dkp = Long.parseLong(cell.getCell().getValue());
						Person p = new Person(name);
						p.setTotalDkp(total_dkp);
						res.add(p);
					}
					catch (NumberFormatException e)
					{
						e.printStackTrace();
					}

				}
				if (ModsLoader.debugMode)
				{
					// Print the cell's address in A1 notation
					System.out.print(cell.getTitle().getPlainText() + "\t");
					// Print the cell's address in R1C1 notation
					System.out.print(cell.getId().substring(cell.getId().lastIndexOf('/') + 1) + "\t");
					// Print the cell's formula or text value
					System.out.print(cell.getCell().getInputValue() + "\t");
					// Print the cell's calculated value if the cell's value is numeric
					// Prints empty string if cell's value is not numeric
					System.out.print(cell.getCell().getNumericValue() + "\t");
					// Print the cell's displayed value (useful if the cell has a formula)
					System.out.println(cell.getCell().getValue() + "\t");
				}
			}

		}

		catch (Exception e)
		{
			e.printStackTrace();
			Main.LOGGER.severe(e.getMessage());
		}

		return res;
	}

	// Creates a new column after the first 2. Inserts comment & current dkp,
	// google will do the addition:)
	public Boolean updateSpreadsheetData(List<Person> in)
	{
		if (in.size() < 1)
			return false;
		try
		{
			SpreadsheetEntry spreadsheet = service.getEntry(ModsLoader.spreadsheet_feed_url, SpreadsheetEntry.class);

			// find Worksheet DkpLoots
			WorksheetFeed worksheetFeed = service.getFeed(spreadsheet.getWorksheetFeedUrl(), WorksheetFeed.class);
			List<WorksheetEntry> worksheets = worksheetFeed.getEntries();
			WorksheetEntry DkpLootsWorksheet = null;
			for (WorksheetEntry worksheet : worksheets)
			{
				if (worksheet.getTitle().getPlainText().equals("DkpLoots"))
					DkpLootsWorksheet = worksheet;
			}
			if (DkpLootsWorksheet == null)
				return false;
			// make sure we have adequate rights.
			if (!DkpLootsWorksheet.getCanEdit())
				return false;

			// lets start by making sure everyone is in the doc.
			URL cellFeedUrl = new URI(DkpLootsWorksheet.getCellFeedUrl().toString() + "?min-row=2&min-col=1&max-col=1").toURL();
			CellFeed cellFeed = service.getFeed(cellFeedUrl, CellFeed.class);
			ArrayList<String> googlePlayers = new ArrayList<String>();
			for (CellEntry cell : cellFeed.getEntries())
			{
				if (cell.getCell().getValue() != null)
				{
					googlePlayers.add(cell.getCell().getValue());
				}
			}

			String LogStr = new String("Will Save on google doc: ");
			int nb_new_rows = 0;
			List<Person> newPlayers = new ArrayList<Person>();
			for (Person p : in)
			{
				LogStr += p.getNom() + "(" + p.getCurrentDkp() + ") ";
				if (!googlePlayers.contains(p.getNom()))
				{
					nb_new_rows += 1;
					newPlayers.add(p);
				}
			}
			Main.LOGGER.info(LogStr);

			if (ModsLoader.debugMode)
			{
				System.out.println("Spreadsheetentry name: " + spreadsheet.getTitle().getPlainText());
				System.out.println("googlePlayers list: " + googlePlayers.toString());
				System.out.println("nb_new_rows" + nb_new_rows);
			}

			// creating the new rows, and adding 2 columns.
			DkpLootsWorksheet.setColCount(DkpLootsWorksheet.getColCount() + 2);
			if (nb_new_rows > 0)
				DkpLootsWorksheet.setRowCount(DkpLootsWorksheet.getRowCount() + nb_new_rows);

			DkpLootsWorksheet = DkpLootsWorksheet.update();

			int max_col = DkpLootsWorksheet.getColCount();
			String date = new SimpleDateFormat("dd-MM-yyyy").format(new Date());

			cellFeedUrl = new URI(DkpLootsWorksheet.getCellFeedUrl().toString() + "?return-empty=true").toURL();
			cellFeed = service.getFeed(cellFeedUrl, CellFeed.class);

			List<CellEntry> allCells = cellFeed.getEntries();
			int pos_row = 0;
			int pos_col = 0;
			String name = null;
			Person new_p = null;
			for (CellEntry cell : allCells)
			{
				pos_row = cell.getCell().getRow();
				pos_col = cell.getCell().getCol();
				if (ModsLoader.debugMode)
					System.out.println(pos_row + ":" + pos_col + " " + cell.getCell().getValue());
				if (pos_row != 1 && pos_col == 1) // player name here
				{
					name = cell.getCell().getValue();
					if (name == null && newPlayers.size() > 0) // lets add a guy.
					{
						new_p = newPlayers.get(newPlayers.size() - 1);
						newPlayers.remove(newPlayers.size() - 1);
						cell.changeInputValueLocal(new_p.getNom());
						cell.update();
					}
				}
				if (pos_row != 1 && pos_col == 2 && name == null) // formula here.
				{
					cell.changeInputValueLocal("=SUM(C" + pos_row + ":" + pos_row + ")");
					cell.update();
				}
				if (pos_col == max_col - 1) // before last column
				{
					if (pos_row == 1) // set title of before last column
					{
						cell.changeInputValueLocal("Comment");
						cell.update();
					}
					else if (name != null && name.length() > 0)
					{ // add comment
						for (Person p : in)
						{
							if (p.getNom().equals(name))
							{
								cell.changeInputValueLocal(p.getComment());
								cell.update();
							}
						}
					}
					else
					{ // a new player here.
						if (new_p != null)
						{
							cell.changeInputValueLocal(new_p.getComment());
							cell.update();
						}
					}
				}
				if (pos_col == max_col) // last column
				{
					if (pos_row == 1) // set title of last column
					{
						cell.changeInputValueLocal(date);
						cell.update();
					}
					else if (name != null && name.length() > 0) // add him dkp
					{
						for (Person p : in)
						{
							if (p.getNom().equals(name))
							{
								cell.changeInputValueLocal(Long.toString(p.getCurrentDkp()));
								cell.update();
							}
						}
					}
					else
					{ // a new player dkp.
						if (new_p != null)
						{
							cell.changeInputValueLocal(Long.toString(new_p.getCurrentDkp()));
							cell.update();
							new_p = null;
						}
					}
				}
			}
		}
		catch (Exception e)
		{
			e.printStackTrace();
			Main.LOGGER.severe(e.getMessage());
			return false;
		}
		return true;
	}

}
